package org.springblade.flow.repair.parts.service.impl;

import com.qiniu.util.Auth;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.flowable.engine.history.HistoricActivityInstance;
import org.flowable.engine.history.HistoricProcessInstance;
import org.flowable.engine.repository.ProcessDefinition;
import org.flowable.engine.task.Comment;
import org.flowable.task.api.Task;
import org.springblade.common.cache.UserCache;
import org.springblade.common.config.ProjectApiConfiguration;
import org.springblade.common.constant.BaseRoleConstant;
import org.springblade.common.constant.MaintenanceSmsConstant;
import org.springblade.common.constant.TemplateMsgConstant;
import org.springblade.common.utils.AsyncHttpUtil;
import org.springblade.core.log.exception.ServiceException;
import org.springblade.core.redis.cache.BladeRedis;
import org.springblade.core.secure.utils.AuthUtil;
import org.springblade.core.tool.constant.BladeConstant;
import org.springblade.core.tool.support.Kv;
import org.springblade.core.tool.utils.*;
import org.springblade.flow.business.service.FlowBusinessService;
import org.springblade.flow.business.service.IFlowService;
import org.springblade.flow.core.constant.ProcessConstant;
import org.springblade.flow.core.entity.BladeFlow;
import org.springblade.flow.core.utils.FlowUtil;
import org.springblade.flow.core.utils.TaskUtil;
import org.springblade.flow.engine.constant.FlowEngineConstant;
import org.springblade.flow.repair.parts.service.IPartsService;
import org.springblade.flow.repair.parts.vo.ProcessTaskVO;
import org.springblade.modules.repair.dto.PartsWorkSaveDTO;
import org.springblade.modules.repair.entity.MaintainPlanContent;
import org.springblade.modules.repair.enums.SourceEnum;
import org.springblade.modules.repair.enums.TaskStatusEnum;
import org.springblade.modules.repair.service.IMaintainPlanContentService;
import org.springblade.modules.repair.service.MaintainPartsWorkService;
import org.springblade.modules.repair.service.WeChatDialogueService;
import org.springblade.modules.repair.vo.PartsSimpleInfoVO;
import org.springblade.modules.resource.utils.SmsUtil;
import org.springblade.modules.system.entity.Role;
import org.springblade.modules.system.entity.User;
import org.springblade.modules.system.service.IUserService;
import org.springblade.modules.system.vo.SimpleUserVO;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.Duration;
import java.util.*;
import java.util.stream.Collectors;

import static org.springblade.flow.repair.parts.constant.PartsProcessConstant.PARTS_HISTORY_TASK;

/**
 * @Description
 * @Author ysq
 * @Date 2022/6/28
 **/

@Slf4j
@Service
@AllArgsConstructor
public class PartsServiceImpl implements IPartsService {

	private final IFlowService flowService;
	private final FlowBusinessService flowBusinessService;
	private final IMaintainPlanContentService maintainPlanContentService;
	private final MaintainPartsWorkService maintainPartsWorkService;
	private final BladeRedis bladeRedis;
	@Lazy
	private final IUserService userService;
	private final WeChatDialogueService weChatDialogueService;
	private final AsyncHttpUtil asyncHttpUtil;
	private final ProjectApiConfiguration projectApiConfiguration;

	@Deprecated
	@Override
	public Long createPartsPlan(PartsWorkSaveDTO partsWorkSave) {

		List<Role> roleList = userService.getRoleByUserId(AuthUtil.getUserId());
//		// 维保组长、维保经理、管理后台跳过审核
//		long checkSkip = roleList.stream().filter(t -> Func.equalsSafe(t.getRoleAlias(), BaseRoleConstant.MAINTENANCE_GROUP_LEADER)
//			|| Func.equalsSafe(t.getRoleAlias(), BaseRoleConstant.MAINTENANCE_MANAGER)).count();
//		boolean skip = ( checkSkip > 0 || Func.equalsSafe(SourceEnum.MANAGEMENT_SIDE.getId(), partsWorkSave.getSource())) ? true : false;
		/**
		 * 2024/2/2 需求变更
		 * 审核环节全部跳过
		 */
		boolean skip = true;
		partsWorkSave.setSkip(skip);
		Long planId = this.startProcess(partsWorkSave);
		if (skip && planId > 0) {
			MaintainPlanContent maintainPlanContent = maintainPlanContentService.getById(planId);
			List<Task> tasks = flowService.getTaskByProcessInstanceId(maintainPlanContent.getProcessInstanceId());
			if (Func.isNotEmpty(tasks)) {
				BladeFlow flow = new BladeFlow();
				flow.setTaskId(tasks.get(0).getId());
				flow.setProcessInstanceId(maintainPlanContent.getProcessInstanceId());
				flow.setFlag("ok");
				flowBusinessService.completeTask(flow);
			}

		}
		return planId;
	}

	@Deprecated
	@Transactional(rollbackFor = Exception.class)
	@Override
	public Long startProcess(PartsWorkSaveDTO partsWorkSave) {
//		String businessTable = FlowUtil.getBusinessTable(ProcessConstant.PARTS);
//		ProcessDefinition processDefinition = flowService.getProcessDefinitionByKey(ProcessConstant.PARTS);
//		if (Func.isEmpty(processDefinition)) {
//			throw new ServiceException("未找到对应配置流程");
//		}

//		// 保存工单
//		 Long businessId = maintainPartsWorkService.savePartsWork(partsWorkSave);
//		// 启动流程
//		Kv variables = Kv.create()
//			.set(ProcessConstant.TASK_VARIABLE_CREATE_USER, AuthUtil.getUserName())
//			.set(ProcessConstant.TASK_VARIABLE_CREATE_USER_ID, AuthUtil.getUserId())
//			.set(ProcessConstant.BUSINESS_ID, businessId)
//			.set("skip", partsWorkSave.getSkip());
//		BladeFlow flow = flowService.startProcessInstanceById(processDefinition.getId(), FlowUtil.getBusinessKey(businessTable, String.valueOf(businessId)), variables);
//		if (Func.isNotEmpty(flow)) {
//			log.debug("配件更换流程已启动,流程ID:" + flow.getProcessInstanceId());
//			// 返回流程id写入业务表
//			MaintainPlanContent maintainPlanContent = new MaintainPlanContent();
//			maintainPlanContent.setId(businessId);
//			maintainPlanContent.setProcessDefinitionId(processDefinition.getId());
//			maintainPlanContent.setProcessInstanceId(flow.getProcessInstanceId());
//			maintainPlanContentService.updateById(maintainPlanContent);
//			// 同步数据到飞书
//			partsWorkSave.setPlanId(businessId);
//			String tenantId = AuthUtil.getTenantId();
//			if("592800".equals(tenantId)){
//				asyncHttpUtil.createPost(projectApiConfiguration.getWeb() + "/admin/feishu/parts/addPartsMessage", Func.toJson(partsWorkSave), WebUtil.getRequest());
//			}
//		} else {
//			throw new ServiceException("开启流程失败");
//		}
//
//		return businessId;
		return null;
	}

	@Override
	public boolean reminder(String processInstanceId) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getMaintainPlanByProcessInstanceId(processInstanceId);
		if (Func.isEmpty(maintainPlanContent)) {
			throw new ServiceException("未找到对应申请工单");
		}

		if (TaskStatusEnum.PARTS_APPROVE.getStatus() != maintainPlanContent.getStatus()) {
			throw new ServiceException("流程已审批，无需催办");
		}

		if (!Func.equalsSafe(AuthUtil.getUserId(),maintainPlanContent.getCreateUser())) {
			throw new ServiceException("您不是申请人，不能进行催办");
		}

		String reminderKey = TemplateMsgConstant.PARTS_REMINDER_KEY.concat(StringPool.DASH).concat(String.valueOf(maintainPlanContent.getId()));
		long count;
		if (bladeRedis.exists(reminderKey)) {
			count = bladeRedis.incr(reminderKey);
		} else {
			count = bladeRedis.incr(reminderKey);
			bladeRedis.expire(reminderKey, Duration.ofDays(1));
		}

		if (count > 2){
			throw new ServiceException("您今天的催办次数已经超过上限!");
		}

		List<Task> tasks = flowService.getTaskByProcessInstanceId(processInstanceId);
		if (Func.isEmpty(tasks)) {
			return false;
		}

		PartsSimpleInfoVO partsSimpleInfo = maintainPartsWorkService.getPartsSimpleInfo(processInstanceId);
		List<Long> taskUserId = tasks.stream().map(t -> TaskUtil.getUserId(t.getAssignee())).collect(Collectors.toList());
		for (Long approveUser : taskUserId) {
			SimpleUserVO approveUserInfo = userService.getSimpleUserInfo(approveUser);
			if (Func.isNotEmpty(approveUserInfo.getOpenid())) {
				// 跳转链接
				String skipUrl = String.format("pages/approve/partApprovalDetail?type=2&id=%s", partsSimpleInfo.getId());
				Map<String, String> templateDataMap = new HashMap<>(8);
				templateDataMap.put("first", String.format("%s的配件申请需要您审核", partsSimpleInfo.getRealName()));
				templateDataMap.put("keyword1", String.format("%s-%s", partsSimpleInfo.getBuildingName(), partsSimpleInfo.getElevatorAddress()));
				templateDataMap.put("keyword2", String.format("%s,型号 {%s},数量：%s个", partsSimpleInfo.getPartsName(), partsSimpleInfo.getPartsModel(), partsSimpleInfo.getNum()));
				templateDataMap.put("keyword3", partsSimpleInfo.getApplyDesc());
				templateDataMap.put("keyword4", String.format("%s%s", partsSimpleInfo.getRealName(), partsSimpleInfo.getPhone()));
				templateDataMap.put("remark", "请尽快审核!");
				templateDataMap.put("params",skipUrl);
				log.info("===========发送配件审批模板消息,审批人:[{}]===========", approveUserInfo.getUserName());
				weChatDialogueService.sendMsg(approveUserInfo.getOpenid(), TemplateMsgConstant.T_REPAIR_APPROVE_ID, templateDataMap);

				log.info("===========发送配件审批短信,审批人:[{}], 手机号码:[{}]===========", approveUserInfo.getUserName(), approveUserInfo.getPhone());
				Map<String, String> smsParam = new HashMap<>(2);
				smsParam.put("auditType", "【待审批】");
				smsParam.put("auditPosition", "【配件审批】");
				SmsUtil.sendMessage(MaintenanceSmsConstant.MAINTENANCE_AUDIT, BladeConstant.ADMIN_TENANT_ID, smsParam, approveUserInfo.getPhone());
			}
		}
		return true;
	}

	@Deprecated
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean cancel(String processInstanceId) {
		MaintainPlanContent maintainPlanContent = maintainPlanContentService.getMaintainPlanByProcessInstanceId(processInstanceId);
		if (Func.isEmpty(maintainPlanContent)) {
			throw new ServiceException("未找到对应申请工单");
		}

		if (TaskStatusEnum.PARTS_APPROVE.getStatus() != maintainPlanContent.getStatus()) {
			throw new ServiceException("流程已审批，不能撤回申请");
		}

		if (!Func.equalsSafe(AuthUtil.getUserId(),maintainPlanContent.getCreateUser())) {
			throw new ServiceException("您不是申请人，不能撤回申请");
		}

		flowBusinessService.deleteProcessAndHistory(processInstanceId, null);
		ProcessTaskVO processTaskVO = new ProcessTaskVO();
		processTaskVO.setProcessInstanceId(processInstanceId);
		processTaskVO.setStatus(String.valueOf(TaskStatusEnum.PARTS_WITHDRAW.getStatus()));
		maintainPartsWorkService.updatePartsWorkStatus(processTaskVO);
		return true;
	}

	@Override
	public List<BladeFlow> historyFlowList(String processInstanceId) {
		List<BladeFlow> flowList = new LinkedList<>();
		List<HistoricActivityInstance> historicActivityInstanceList = flowService.historyFlowList(processInstanceId);
		// 正在运行（未审批）的节点
		List<HistoricActivityInstance> curTaskList = new ArrayList<>();
		Arrays.sort(PARTS_HISTORY_TASK);
		for (int i = 0; i < historicActivityInstanceList.size(); i++) {
			HistoricActivityInstance historicActivityInstance = historicActivityInstanceList.get(i);
			// 过滤非处理人节点
			if ("MI_END".equals(historicActivityInstance.getDeleteReason())) {
				continue;
			}
			// 显示开始节点和结束节点，并且执行人不为空的任务
			if (Arrays.binarySearch(PARTS_HISTORY_TASK, historicActivityInstance.getActivityId()) >= 0) {
				if (Func.isEmpty(historicActivityInstance.getEndTime())) {
					curTaskList.add(historicActivityInstance);
					continue;
				}
				BladeFlow flow = new BladeFlow();
				flow.setHistoryActivityId(historicActivityInstance.getActivityId());
				flow.setHistoryActivityName(historicActivityInstance.getActivityName());
				flow.setCreateTime(historicActivityInstance.getStartTime());
				flow.setEndTime(historicActivityInstance.getEndTime());
				String durationTime = DateUtil.secondToTime(Func.toLong(historicActivityInstance.getDurationInMillis(), 0L) / 1000);
				flow.setHistoryActivityDurationTime(durationTime);
				// 获取流程发起人名称
				if (FlowEngineConstant.START_EVENT.equals(historicActivityInstance.getActivityType())) {
					List<HistoricProcessInstance> processInstanceList = flowService.processInstanceList(processInstanceId);
					if (processInstanceList.size() > 0) {
						if (StringUtil.isNotBlank(processInstanceList.get(0).getStartUserId())) {
							String taskUser = processInstanceList.get(0).getStartUserId();
							User user = UserCache.getUser(TaskUtil.getUserId(taskUser));
							if (user != null) {
								flow.setAssignee(historicActivityInstance.getAssignee());
								flow.setAssigneeName(user.getRealName());
							}
						}
					}
				}
				// 获取任务执行人名称
				if (StringUtil.isNotBlank(historicActivityInstance.getAssignee())) {
					User user = UserCache.getUser(TaskUtil.getUserId(historicActivityInstance.getAssignee()));
					if (user != null) {
						flow.setAssignee(historicActivityInstance.getAssignee());
						flow.setAssigneeName(user.getRealName());
					}
				}
				// 获取意见评论内容
				if (StringUtil.isNotBlank(historicActivityInstance.getTaskId())) {
					List<Comment> commentList = flowService.getTaskComments(historicActivityInstance.getTaskId());
					if (commentList.size() > 0) {
						flow.setComment(commentList.get(0).getFullMessage());
					}
				}
				flowList.add(flow);
			}
		}

		// 处理正在审批的节点
		if (curTaskList.size() > 0) {
			HistoricActivityInstance curActivityInstance = curTaskList.get(0);
			BladeFlow flow = new BladeFlow();
			flow.setHistoryActivityId(curActivityInstance.getActivityId());
			flow.setHistoryActivityName(curActivityInstance.getActivityName());
			flow.setCreateTime(curActivityInstance.getStartTime());
			// 获取任务执行人名称
			List<Long> assigneeList = curTaskList.stream().map(t -> TaskUtil.getUserId(t.getAssignee())).collect(Collectors.toList());
			List<String> assigneeNameList = new ArrayList<>();
			for (Long assignee : assigneeList) {
				User user = UserCache.getUser(assignee);
				if (user != null) {
					assigneeNameList.add(user.getRealName());
				}
			}
			flow.setAssignee(assigneeList.stream().map(t -> String.valueOf(t)).collect(Collectors.joining("、")));
			flow.setAssigneeName(assigneeNameList.stream().collect(Collectors.joining("、")));
			flowList.add(flow);
		}

		return flowList;
	}
}
